package com.tcm.doctor.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.base.core.dozer.DozerConvert;
import com.base.core.lang.DateUtils;
import com.base.core.utils.R;
import com.base.genid.generator.UidGenerator;
import com.tcm.doctor.domain.dto.CashDrawsDTO;
import com.tcm.doctor.domain.dto.DoctorFlowDto;
import com.tcm.doctor.domain.entity.CashDraws;
import com.tcm.doctor.domain.entity.DoctorAccount;
import com.tcm.doctor.domain.enums.BusinessCodeEnum;
import com.tcm.doctor.mapper.CashDrawsMapper;
import com.tcm.doctor.mapper.DoctorAccountMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@DubboService(version = "0.0.1-alpha", retries = 3, timeout = 6000, delay = -1)
public class DoctorCashDrawServiceImpl implements DoctorCashDrawsService {

    @Autowired
    private CashDrawsMapper doctorExtractMapper;

    @Autowired
    private DoctorAccountMapper doctorAccountMapper;

    @DubboReference(version = "0.0.1-beta", group = "cached-uid", timeout = 6000, check = false, retries = 3)
    private UidGenerator uidGenerator;

    @DubboReference(version = "0.0.1-alpha", timeout = 6000, retries = 3, check = false)
    private DoctorFlowService doctorFlowService;

    @DubboReference(version = "0.0.1-alpha", timeout = 6000, retries = 3, check = false)
    private DoctorServicesService configService;

    /**
     * 获得单条信息
     *
     * @param id
     * @return Doctor
     */
    @Override
    public CashDrawsDTO findById(Long id) {
        CashDraws doctorExtract = doctorExtractMapper.selectByPrimaryKey(id);
        CashDrawsDTO doctorExtractVo = null;
        if (ObjectUtil.isNotEmpty(doctorExtract)) {
            doctorExtractVo = DozerConvert.copyProperties(doctorExtract, CashDrawsDTO.class);
        }
        return doctorExtractVo;
    }


    /**
     * 新增信息
     *
     * @param doctorExtractDto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(CashDrawsDTO doctorExtractDto) throws Exception {

        //判断id是否为空
        if (doctorExtractDto.getTargetId().equals(0L)) {
            R.throwFail(BusinessCodeEnum.DOCTOR_USER_ID_NOT_EXISTS);
        }

        //判断金额是否为空
        if (ObjectUtil.isEmpty(doctorExtractDto.getMoney())) {
            R.throwFail(BusinessCodeEnum.MONEY_NOT_EXISTS);
        }

        //判断金额是否充足
        DoctorAccount doctorAccount = doctorAccountMapper.findByUserId(doctorExtractDto.getTargetId());
        if (ObjectUtil.isNull(doctorAccount)) {
            R.throwFail(BusinessCodeEnum.CURRENT_MONEY_NOT_ENOUGH);
        }

        if (NumberUtil.isLess(doctorAccount.getCurrentMoney(),doctorExtractDto.getMoney())) {
            R.throwFail(BusinessCodeEnum.CURRENT_MONEY_NOT_ENOUGH);
        }

        //判断是否是最低提现金额
        BigDecimal doctorsWithdraw = new BigDecimal(
                configService.findValue(doctorExtractDto.getTargetId(),"doctors_withdraw","100"));
        if (doctorExtractDto.getMoney().compareTo(doctorsWithdraw) < 0){
            R.throwFail(BusinessCodeEnum.AMOUNT_IS_NOT_REACHED);
        }


        CashDraws doctorExtract = DozerConvert.copyProperties(doctorExtractDto, CashDraws.class);
        doctorExtract.setStatus(new Byte("0"));
        doctorExtract.setId(uidGenerator.getUID());
        doctorExtract.setCreateTime(DateUtils.nowTime());
        doctorExtract.setUpdateTime(DateUtils.nowTime());
        doctorExtractMapper.insert(doctorExtract);

        //扣除金额
        doctorAccount.setCurrentMoney(NumberUtil.sub(doctorAccount.getCurrentMoney(),doctorExtractDto.getMoney()));
        doctorAccount.setExtractPrice(NumberUtil.add(doctorAccount.getExtractPrice(),doctorExtractDto.getMoney()));
        doctorAccountMapper.update(doctorAccount);
//        //添加提现记录
//        DoctorFlowDto doctorFlowDto = new DoctorFlowDto();
//        doctorFlowDto.setUserId(doctorExtract.getTargetId());
//        doctorFlowDto.setMemo("提现申请扣除金额");
//        doctorFlowDto.setMoney(doctorExtractDto.getMoney());
//        doctorFlowDto.setType(new Short("6"));
//        doctorFlowDto.setPayType(new Byte("0"));
//        doctorFlowService.save(doctorFlowDto);
    }


    /**
     * 永久删除
     *
     * @param id
     */
    @Override
    public void delete(Long id) {
        doctorExtractMapper.deleteByPrimaryKey(id);
    }

    /**
     * 代付成功
     * @param merBillNo
     * @param billNo
     */
    @Override
    public void success(String merBillNo, String billNo) {
        CashDraws doctorExtract = doctorExtractMapper.selectByPrimaryKey(Long.valueOf(merBillNo));
        doctorExtract.setStatus(new Byte("2"));
        doctorExtract.setUpdateTime(DateUtils.nowTime());
        doctorExtract.setBillNo(billNo);
        doctorExtractMapper.update(doctorExtract);
    }

    /**
     * 转账退回
     * @param merBillNo
     * @param billNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void fail(String merBillNo, String billNo) throws Exception {
        CashDraws doctorExtract = doctorExtractMapper.selectByPrimaryKey(Long.valueOf(merBillNo));
        doctorExtract.setStatus(new Byte("-1"));
        doctorExtract.setUpdateTime(DateUtils.nowTime());
        doctorExtract.setBillNo(billNo);
        doctorExtractMapper.update(doctorExtract);

        //退还金额
        DoctorAccount doctorAccount = doctorAccountMapper.findByUserId(doctorExtract.getTargetId());
        doctorAccount.setCurrentMoney(NumberUtil.add(doctorAccount.getCurrentMoney(),doctorExtract.getMoney()));
        doctorAccount.setExtractPrice(NumberUtil.sub(doctorAccount.getExtractPrice(),doctorExtract.getMoney()));
        doctorAccount.setUpdateTime(LocalDateTime.now());

        //资金明细
        DoctorFlowDto doctorFlowDto = new DoctorFlowDto();
        doctorFlowDto.setUserId(doctorExtract.getTargetId());
        doctorFlowDto.setMemo("提现申请失败退回金额");
        doctorFlowDto.setMoney(doctorExtract.getMoney());
        doctorFlowDto.setType(new Short("6"));
        doctorFlowDto.setPayType(new Byte("1"));
        doctorFlowService.save(doctorFlowDto);
    }


}

